package org.activequant.data.util.subscription;

import java.util.concurrent.Executor;

import org.activequant.core.domainmodel.data.MarketDataEntity;
import org.activequant.data.retrieval.SubscriptionSourceBase;

/**
 * Common base for Subscription sources that want to use a specific thread for
 * event distribution.
 * <p>
 * IMPORTANT: use fireEventInExecutorThread to fire market events. Do <em>NOT</em> use fire Event method!<br/>
 * An abstract class. ExecutorSubscriptionSourceBase&lt;T extends MarketDataEntity&lt;T&gt;&gt; extends SubscriptionSourceBase&lt;T&gt;.<br/>
 * Defines a nested abstract ThreadSubscription class. Holds the following associated variables:
 * <ul>
 * <li>executor(Executor)</li>
 * </ul>
 * Holds the following inherited variables:
 * <ul>
 * <li>activeBackends(Map&lt;Topic, Subscription&gt;)</li>
 * <li>activeSubscriptions(Queue&lt;SubscriptionDelegate&gt;)</li>
 * </ul>
 * <br/>
 * <b>History:</b><br>
 *  - [03.02.2008] Created (Mike Kroutikov)<br>
 *
 *  @author Mike Kroutikov
 */
public abstract class ExecutorSubscriptionSourceBase<T extends MarketDataEntity<T>> extends SubscriptionSourceBase<T> {
	/**
	 * private final Executor executor;
	 */
	private final Executor executor;
	/**
	 * constructs an ExecutorSubscriptionSourceBase&lt;T extends MarketDataEntity&lt;T&gt;&gt;(extends SubscriptionSourceBase&lt;T&gt;) using the given executor(Executor)
	 * to set its associated executor(Executor)
	 * @param executor
	 */
	public ExecutorSubscriptionSourceBase(Executor executor) {
		this.executor = executor;
	}
	/**
	 * An abstract protected class. Subscription subclass. Holds the following inherited variables:
	 * <ul>
	 * <li>isActive(AtomicBoolean)</li>
	 * <li>refCount(AtomicInteger)</li>
	 * <li>instrument(InstrumentSpecification)</li>
	 * <li>event(Event&lt;T&gt;)</li>
	 * </ul>
	 * @author Dimitar
	 *
	 */
	protected abstract class ThreadSubscription extends Subscription {
		
		/**
		 * Call this function to distribute market entity.<br/>
		 * fires the given event(T) from within a Runnable's run() method on the executor(Executor)
		 * which then invokes <code>event.fire(data)</code> on the inherited event(Event&lt;T&gt;) using the given event(T)
		 * @param event market data entity.
		 */
		protected void fireEventInExecutorThread(final T event) {
			executor.execute(new Runnable() {
				public void run() {
					fireEvent(event);
				}
			});
		}
	}
}
